package com.ruoyi.parttime.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.ruoyi.common.annotation.AutoFill;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.kafka.KafkaProducer;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.parttime.domain.ApplyForParrtime;
import com.ruoyi.parttime.domain.MonthData;
import com.ruoyi.parttime.domain.ParttimePublish;
import com.ruoyi.parttime.domain.vo.ApplyForParrtimeVo;
import com.ruoyi.parttime.mapper.ApplyForParrtimeMapper;
import com.ruoyi.parttime.mapper.ParttimePublishMapper;
import com.ruoyi.parttime.service.IApplyForParrtimeService;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.rmi.CORBA.Util;

/**
 * 兼职申请Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-02
 */
@Service
public class ApplyForParrtimeServiceImpl implements IApplyForParrtimeService {
    @Autowired
    private ApplyForParrtimeMapper applyForParrtimeMapper;

    @Autowired
    private ParttimePublishMapper parttimePublishMapper;

    @Autowired
    RedisCache redisCache;
    @Autowired
    KafkaProducer kafkaProducer;

    /**
     * 查询兼职发布
     *
     * @param id 兼职发布主键
     * @return 兼职发布
     */

    @Override
    public ParttimePublish selectParttimePublishById(Long id) {
        ApplyForParrtime apply = applyForParrtimeMapper.selectApplyForParrtimeById(id);
        return parttimePublishMapper.selectParttimePublishById(apply.getParttimePublishId());
    }

    /**
     * 查询兼职申请详细信息
     *
     * @param id 兼职发布主键
     * @return 兼职申请
     */
    @Override
    public ApplyForParrtime selectApplyParttimePublishById(Long id) {
        return applyForParrtimeMapper.selectApplyForParrtimeById(id);
    }

    /**
     * 查询本人兼职申请列表
     *
     * @param applyForParrtimeVo 兼职申请
     * @return 兼职申请
     */
    @Override
    public List<ApplyForParrtimeVo> selectApplyForParrtimeList(ApplyForParrtimeVo applyForParrtimeVo) {
        //获取当前用户id,并且存入applyForParrtime中，用于作为查询条件
        applyForParrtimeVo.setApplyForUserId(SecurityUtils.getLoginUser().getUserId());
        List<ApplyForParrtimeVo> applyForParrtimeVoList = applyForParrtimeMapper.selectApplyForParrtimeAndParttimePublish(applyForParrtimeVo);
        return applyForParrtimeVoList;
    }

    /**
     * 查询申请自己发布的兼职的列表
     *
     * @param applyForParrtime 兼职申请
     * @return 兼职申请
     */
    @Override
    public List<ApplyForParrtime> selectApplyForParrtime(ApplyForParrtime applyForParrtime) {
        //获取当前用户id,并且存入applyForParrtime中，用于作为查询条件
        applyForParrtime.setPublishUserId(SecurityUtils.getLoginUser().getUserId());
        //默认查询待审核状态的申请:0
        applyForParrtime.setApplyForStatus(0);
        return applyForParrtimeMapper.selectApplyForParrtimeList(applyForParrtime);
    }

    /**
     * 查询今日兼职申请成功或失败数
     *
     * @return 兼职申请数
     */
    @Override
    public Map<Integer, Integer> getStatisticsNumBystatus() {
        LocalDateTime startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.now();
        return applyForParrtimeMapper.getStatisticsNumBystatus(startTime, endTime);
    }

    /**
     * 获取本年兼职失败和成功数量
     *
     * @return
     */
    @Override
    public Map<String, List<String>> getMonthNum() {
        List<MonthData> list = applyForParrtimeMapper.getMonthNum();
        Map<String, List<String>> map = new HashMap<>();
        map.put("monthList",list.stream().map(s->s.getMonths()).distinct().collect(Collectors.toList()));
        map.put("stateList1",list.stream().filter(s->s.getState()==1).map(s->s.getTotality().toString()).collect(Collectors.toList()));
        map.put("stateList2",list.stream().filter(s->s.getState()==2).map(s->s.getTotality().toString()).collect(Collectors.toList()));
        return map;
    }

    /**
     * 查询今日兼职申请数
     *
     * @return 兼职申请数
     */
    @Override
    public Integer getStatisticsNum() {
        LocalDateTime startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.now();
        return applyForParrtimeMapper.getStatisticsNum(startTime, endTime);
    }

    @Override
    public List<ApplyForParrtime> getByTimeList(Integer status, LocalDateTime time) {
        return applyForParrtimeMapper.getByTimeList(status, time);
    }

    @Override
    public ApplyForParrtime selectApplyForParrtimeBypublishId(Long parttimePublishId) {
        //获取当前用户的userId
        Long userId = SecurityUtils.getLoginUser().getUserId();
        return applyForParrtimeMapper.selectApplyForParrtimeBypublishId(parttimePublishId, userId);
    }

    @Override
    public int updateApplyForStatusById(Long id, Integer status) {
        return applyForParrtimeMapper.updateApplyForStatusById(id, status);
    }

    /**
     * 新增兼职申请
     *
     * @param applyForParrtime 兼职申请
     * @return 结果
     */
    @Override
    @AutoFill(value = BusinessType.INSERT)
    public int insertApplyForParrtime(ApplyForParrtime applyForParrtime) {
        //获取当前操作的用户的信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        //填入申请者id
        applyForParrtime.setApplyForUserId(loginUser.getUserId());
        //填入申请者的用户名
        applyForParrtime.setUsername(loginUser.getUsername());
        //默认申请状态为0：申请中
        applyForParrtime.setApplyForStatus(0);
        return applyForParrtimeMapper.insertApplyForParrtime(applyForParrtime);
    }

    /**
     * 修改兼职申请
     *
     * @param applyForParrtime 兼职申请
     * @return 结果
     */
    @Override
    @AutoFill(value = BusinessType.UPDATE)
    public int updateApplyForParrtime(ApplyForParrtime applyForParrtime) {
        //通过主键id查到,对应的申请
        ApplyForParrtime apply1 = applyForParrtimeMapper.selectApplyForParrtimeById(applyForParrtime.getId());
        //删除缓存的申请数据
        if (applyForParrtime.getApplyForStatus() == 2) {
            redisCache.deleteObject(apply1.getApplyForUserId().toString() + "-" + apply1.getParttimePublishId().toString());
        }
        int mark = applyForParrtimeMapper.updateApplyForParrtime(applyForParrtime);
        if (mark > 0) {
            kafkaProducer.sendMessage("my_topic", "兼职数据发生更新");
        }
        return mark;
    }

    /**
     * 批量删除兼职申请
     *
     * @param ids 需要删除的兼职申请主键
     * @return 结果
     */
    @Override
    public int deleteApplyForParrtimeByparttimePublishIds(Long[] ids) {
        return applyForParrtimeMapper.deleteApplyForParrtimeByparttimePublishIds(ids);
    }

    /**
     * 撤销兼职申请，直接删除此数据
     *
     * @param id 兼职申请主键
     * @return 结果
     */
    @Override
    public int deleteApplyForParrtimeById(Long id) {
        //获取用户id
        String userId = SecurityUtils.getUserId().toString();
        //从缓存中删除此用户的申请的兼职信息
        ApplyForParrtime apply = applyForParrtimeMapper.selectApplyForParrtimeById(id);
        redisCache.deleteObject(userId + "-" + apply.getParttimePublishId());
        return applyForParrtimeMapper.deleteApplyForParrtimeById(id);
    }
}
